package com.oauth.service.members.dao;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.jdo.Transaction;

import org.springframework.stereotype.Repository;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.oauth.logging.OAuthLogger;
import com.oauth.service.jdosupport.PersistenceFactory;
import com.oauth.service.members.beans.Member;

@Repository
public class MemberDAOImpl implements MemberDAO {

	private OAuthLogger logger = OAuthLogger.getLogger(this.getClass());

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.spradeep.profile.dao.impl.MemberDAO#createMember(java.lang.String,
	 * java.lang.String, java.lang.String, java.util.Date,
	 * com.spradeep.profile.constants.Gender, java.lang.String)
	 */
	public Member addMember(Member member) {
		PersistenceManager persistenceManager = PersistenceFactory.get().getPersistenceManager();
		member.setCreationDate(new Date());
		member.setLastUpdateDate(new Date());
		member.setLastLogin(new Date());
		try {
			member = persistenceManager.makePersistent(member);
		} finally {
			persistenceManager.close();
		}
		return member;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.spradeep.profile.dao.impl.MemberDAO#updateMember(com.spradeep.profile
	 * .beans.Member)
	 */
	public boolean updateMember(Member member) {
		// Set the last update date to current date.
		member.setLastUpdateDate(new Date());
		PersistenceManager persistenceManager = PersistenceFactory.get().getPersistenceManager();
		try {
			member = persistenceManager.makePersistent(member);
		} finally {
			persistenceManager.close();
		}
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.spradeep.profile.dao.impl.MemberDAO#getMember(java.lang.Long)
	 */
	@SuppressWarnings("unchecked")
	public Member getMember(Long memberId) {
		PersistenceManager persistenceManager = PersistenceFactory.get().getPersistenceManager();
		Query query = persistenceManager.newQuery(Member.class);
		query.setFilter("memberId == memberIdParam");
		query.declareParameters("Long memberIdParam");
		List<Member> results;
		try {
			results = (List<Member>) query.execute(memberId);
			if (results == null || results.isEmpty()) {
				return null;
			}
			if (results.size() > 1) {
				logger.error("Found duplicate for member=" + memberId);
			}
			return results.get(0);
		} finally {
			persistenceManager.close();
		}

	}

	public List<String> getNewUsers(int interval) {
		DatastoreService datastoreService = DatastoreServiceFactory.getDatastoreService();
		com.google.appengine.api.datastore.Query query = new com.google.appengine.api.datastore.Query(
				"Member");
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DAY_OF_MONTH, interval);
		query.addFilter("creationDate", FilterOperator.GREATER_THAN_OR_EQUAL, calendar.getTime());
		PreparedQuery pq = datastoreService.prepare(query);
		List<String> emailList = new ArrayList<String>();
		for (Entity result : pq.asIterable()) {
			String email = (String) result.getProperty("email");
			emailList.add(email);
		}
		return emailList;
	}

	public List<String> getActiveUsers(int interval) {
		DatastoreService datastoreService = DatastoreServiceFactory.getDatastoreService();
		com.google.appengine.api.datastore.Query query = new com.google.appengine.api.datastore.Query(
				"Member");
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DAY_OF_MONTH, interval);
		Date intervalDate = calendar.getTime();

		query.addFilter("lastLogin", FilterOperator.GREATER_THAN_OR_EQUAL, intervalDate);

		PreparedQuery pq = datastoreService.prepare(query);
		List<String> emailList = new ArrayList<String>();
		for (Entity result : pq.asIterable()) {
			String email = (String) result.getProperty("email");
			Date creationDate = (Date) result.getProperty("creationDate");
			if (creationDate.before(intervalDate)) {
				emailList.add(email);
			}
		}
		return emailList;
	}

	@SuppressWarnings("rawtypes")
	public Long getCount() {
		DatastoreService datastoreService = DatastoreServiceFactory.getDatastoreService();
		PreparedQuery prepare = datastoreService
				.prepare(new com.google.appengine.api.datastore.Query("Member"));
		return (long) prepare.countEntities();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.spradeep.profile.dao.impl.MemberDAO#deleteMember(java.lang.Long)
	 */
	public boolean deleteMember(Member member) {
		PersistenceManager persistenceManager = PersistenceFactory.get().getPersistenceManager();
		Transaction tx = persistenceManager.currentTransaction();

		try {
			tx.begin(); // Begin the transaction
			persistenceManager.deletePersistent(member); // Delete if exists.
			tx.commit();
		} finally {
			if (tx.isActive()) {
				tx.rollback();
			}
			persistenceManager.close();
		}

		return true;
	}

	@SuppressWarnings("unchecked")
	public Member getMember(String pEmailId) {
		PersistenceManager persistenceManager = PersistenceFactory.get().getPersistenceManager();
		Query query = persistenceManager.newQuery(Member.class);
		query.setFilter("email == emailParam");
		query.declareParameters("String emailParam");
		try {
			List<Member> results = (List<Member>) query.execute(pEmailId);
			if (results == null || results.isEmpty()) {
				return null;
			} else {
				return results.get(0);
			}

		} finally {
			persistenceManager.close();
		}
	}

}
